package com.afdor.rws.event.support;

import com.afdor.rws.annotation.extension.Extension;
import com.afdor.rws.event.EventSource;
import com.afdor.rws.event.EventSourceManager;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.ToString;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 默认事件源管理器实现
 *
 * @author 悭梵
 * @date Created in 2018-08-14 18:34
 */
@ToString
@EqualsAndHashCode
@Extension(value = "default", order = Extension.NORMAL_ORDER - 100, interfaceClass = EventSourceManager.class)
public class DefaultEventSourceManager implements EventSourceManager {

    /**
     * 是否已初始化
     */
    private volatile boolean init = Boolean.FALSE;
    /**
     * 事件源管理器
     */
    private Map<String, EventSource> eventSourceMap = new ConcurrentHashMap<String, EventSource>();

    @Override
    public <T extends EventSourceManager> T addEventSource(@NonNull EventSource eventSource) {
        if (!init) {
            throw new IllegalStateException("please execute the init method first.");
        }
        eventSourceMap.putIfAbsent(eventSource.getEventSourceName(), eventSource);
        return (T) this;
    }

    /**
     * 移除指定事件源配置信息
     *
     * @param eventSourceName
     */
    public EventSourceManager remove(@NonNull String eventSourceName) {
        if (!init) {
            throw new IllegalStateException("please execute the init method first.");
        }
        eventSourceMap.remove(eventSourceName);
        return this;
    }

    @Override
    public <T extends EventSource> T getEventSource(@NonNull String eventSourceName) {
        if (!init) {
            throw new IllegalStateException("please execute the init method first.");
        }
        return (T) eventSourceMap.get(eventSourceName);
    }

    @Override
    public EventSourceManager init() {
        init = Boolean.TRUE;
        return this;
    }

    @Override
    public void destroy() {
        init = Boolean.FALSE;
        eventSourceMap.values().parallelStream().forEach(eventSource -> eventSource.getChannelProvider().dispose());
        eventSourceMap.clear();
    }
}
